<script setup>
import { ref } from 'vue'
import CodeBlock from '@components/CodeBlock.vue'

// 基本的defineModel用法
const name = defineModel('name')

// 带选项的defineModel用法
const age = defineModel('age', {
  type: Number,
  default: 18,
  // 自定义getter
  get(value) {
    return value || 18 // 确保有默认值
  },
  // 自定义setter
  set(value) {
    return Math.max(0, Math.min(120, value)) // 限制在合理范围内
  }
})

// 内部使用的计数器 - 使用defineModel的简写形式
const counter = defineModel()

// 更新方法
const updateName = () => {
  name.value = name.value + ' ✨'
}

const incrementAge = () => {
  age.value++
}

// 父组件数据（模拟）
const parentData = {
  name: name.value,
  age: age.value,
  counter: counter.value
}

// 原始实现 vs 使用defineModel
// 代码示例相关变量已移除，使用modelExamples对象替代

// 代码示例描述
const modelExamples = {
  traditional: {
    title: '传统v-model实现',
    description: '使用defineProps和defineEmits手动实现双向绑定',
    steps: ['定义props接收modelValue', '定义emit触发update:modelValue事件', '手动调用emit更新值']
  },
  basic: {
    title: '基本defineModel用法',
    description: '一行代码替代传统实现',
    steps: ['声明响应式引用', '直接修改值', 'Vue自动处理事件触发']
  },
  options: {
    title: '带选项的defineModel',
    description: '自定义类型、默认值和转换函数',
    features: ['类型检查', '默认值设置', '自定义getter/setter']
  }
}
</script>
<template>
  <div class="compiler-model-demo">
    <h3>defineModel 演示</h3>
    
    <div class="demo-content">
      <div class="model-examples">
        <!-- 示例1: 基本文本输入 -->
        <div class="model-example">
          <h4>基本文本输入</h4>
          <div class="input-group">
            <label for="name-input">姓名:</label>
            <input 
              id="name-input" 
              v-model="name" 
              type="text" 
              placeholder="请输入姓名"
              class="demo-input"
            />
            <button @click="updateName" class="demo-button">添加装饰</button>
          </div>
          <p class="model-value">当前值: <strong>{{ name }}</strong></p>
        </div>
        
        <!-- 示例2: 带选项的数字输入 -->
        <div class="model-example">
          <h4>带选项的数字输入</h4>
          <div class="input-group">
            <label for="age-input">年龄:</label>
            <input 
              id="age-input" 
              v-model.number="age" 
              type="number" 
              min="0" 
              max="120"
              class="demo-input"
            />
            <button @click="incrementAge" class="demo-button">增加</button>
          </div>
          <p class="model-value">当前值: <strong>{{ age }}</strong></p>
          <small class="hint">注意: 设置了范围限制 (0-120)</small>
        </div>
        
        <!-- 示例3: 默认modelValue -->
        <div class="model-example">
          <h4>计数器示例</h4>
          <div class="counter-group">
            <button @click="counter--" class="demo-button secondary">-</button>
            <span class="counter-value">{{ counter }}</span>
            <button @click="counter++" class="demo-button">+</button>
          </div>
          <p class="model-value">当前值: <strong>{{ counter }}</strong></p>
        </div>
      </div>
      
      <div class="code-comparison">
        <div class="code-section">
          <h4>{{ modelExamples.traditional.title }}</h4>
          <p>{{ modelExamples.traditional.description }}</p>
          <ul>
            <li v-for="(step, index) in modelExamples.traditional.steps" :key="index">{{ index + 1 }}. {{ step }}</li>
          </ul>
        </div>
        
        <div class="code-section">
          <h4>{{ modelExamples.basic.title }}</h4>
          <p>{{ modelExamples.basic.description }}</p>
          <ul>
            <li v-for="(step, index) in modelExamples.basic.steps" :key="index">{{ index + 1 }}. {{ step }}</li>
          </ul>
        </div>
        
        <div class="code-section">
          <h4>{{ modelExamples.options.title }}</h4>
          <p>{{ modelExamples.options.description }}</p>
          <ul>
            <li v-for="feature in modelExamples.options.features" :key="feature">• {{ feature }}</li>
          </ul>
        </div>
      </div>
    </div>
    
    <div class="explanation">
      <h4>defineModel 的优势</h4>
      <ul>
        <li>✅ 一行代码替代了 props 和 emit 的组合</li>
        <li>✅ 直接修改引用值即可更新父组件数据</li>
        <li>✅ 内置类型支持和验证</li>
        <li>✅ 支持自定义 getter 和 setter</li>
        <li>✅ 自动处理 v-model:foo 修饰符</li>
        <li>✅ 更好的 TypeScript 集成</li>
      </ul>
    </div>
    
    <div class="migration-tip">
      <h4>迁移提示</h4>
      <p>从传统 v-model 迁移到 defineModel:</p>
      <ol>
        <li>移除 defineProps 中的 modelValue 定义</li>
        <li>移除 defineEmits 中的 'update:modelValue' 定义</li>
        <li>使用 <code>const model = defineModel()</code> 替代</li>
        <li>在代码中直接使用 <code>model.value</code> 替代 <code>props.modelValue</code></li>
        <li>移除所有 <code>emit('update:modelValue', newValue)</code> 调用，直接修改 <code>model.value = newValue</code></li>
      </ol>
    </div>
  </div>
</template>

<style scoped>
.compiler-model-demo {
  background-color: white;
  border-radius: 8px;
  padding: 1.5rem;
}

.compiler-model-demo h3 {
  color: #42b883;
  margin-bottom: 1rem;
}

.demo-content {
  margin-bottom: 1.5rem;
}

.model-examples {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
  margin-bottom: 2rem;
}

.model-example {
  background-color: #f8f9fa;
  padding: 1.5rem;
  border-radius: 8px;
  border-left: 4px solid #42b883;
}

.model-example h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #333;
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.input-group label {
  font-weight: 500;
  color: #333;
}

.demo-input {
  padding: 0.75rem;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 1rem;
}

.demo-input:focus {
  outline: none;
  border-color: #42b883;
  box-shadow: 0 0 0 2px rgba(66, 184, 131, 0.2);
}

.demo-button {
  background-color: #42b883;
  color: white;
  border: none;
  padding: 0.75rem 1rem;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.9rem;
  transition: background-color 0.2s;
}

.demo-button:hover {
  background-color: #38a169;
}

.demo-button.secondary {
  background-color: #6c757d;
}

.demo-button.secondary:hover {
  background-color: #5a6268;
}

.model-value {
  margin-bottom: 0;
  color: #666;
}

.model-value strong {
  color: #42b883;
}

.hint {
  color: #666;
  font-style: italic;
}

.counter-group {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.counter-value {
  font-size: 1.5rem;
  font-weight: bold;
  min-width: 3rem;
  text-align: center;
  color: #42b883;
}

.code-comparison {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

.code-section {
  background-color: #f8f9fa;
  padding: 1rem;
  border-radius: 6px;
}

.code-section h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #333;
}

.explanation {
  background-color: #e8f5e9;
  padding: 1.5rem;
  border-radius: 6px;
  border-left: 4px solid #4caf50;
  margin-bottom: 1.5rem;
}

.explanation h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #2e7d32;
}

.explanation ul {
  margin: 0;
  padding-left: 1.5rem;
}

.explanation li {
  margin-bottom: 0.5rem;
  color: #333;
}

.migration-tip {
  background-color: #fff3cd;
  padding: 1.5rem;
  border-radius: 6px;
  border-left: 4px solid #ffc107;
}

.migration-tip h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #856404;
}

.migration-tip ol {
  margin: 0;
  padding-left: 1.5rem;
}

.migration-tip li {
  margin-bottom: 0.5rem;
  color: #333;
}

.migration-tip code {
  background-color: #f8f9fa;
  padding: 0.2rem 0.4rem;
  border-radius: 4px;
  font-family: 'Monaco', 'Menlo', monospace;
}

/* 响应式布局 */
@media (max-width: 768px) {
  .model-examples,
  .code-comparison {
    grid-template-columns: 1fr;
  }
}
</style>